package cn.sc.summer.security.provider;

import cn.sc.summer.security.provider.base.BaseAuthenticationProvider;
import cn.sc.summer.security.service.user.lock.base.BaseUserLockCheck;
import cn.sc.summer.security.token.LoginToken;
import cn.sc.summer.token.enums.LoginTypeEnum;
import cn.sc.summer.token.po.UserDetailX;
import cn.sc.summer.token.util.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * 类名：手机号密码登录密码验证规则
 *
 * @author a-xin
 * @date 2023/11/22 17:07
 */
@Slf4j
@Service
public class LoginAuthenticationProvider extends BaseAuthenticationProvider {

    private static final long serialVersionUID = -7986524151849721722L;

    /**
     * 正式验证用户信息之前，进行用户数据验证，比如，是否黑名单，是否限制登录等
     *
     * @param authentication 验证信息
     */
    @Override
    protected void preCheckUser(Authentication authentication) {
    }

    /**
     * 进行用户信息验证
     *
     * @param userDetailX    用户信息
     * @param authentication 登录凭证
     */
    @Override
    protected void postCheckUser(UserDetailX userDetailX, Authentication authentication) throws Throwable {
        String password = String.valueOf(authentication.getCredentials());
        if (!Objects.equals(AESUtil.encrypt(password, userDetailX.getAcesskey()), userDetailX.getPassword())) {
            BaseUserLockCheck userLockCheck = getUserLockCheck();
            userLockCheck.addUserLoginLock(userDetailX.getUserId());
            throw new AuthenticationServiceException("The account or password is incorrect！");
        }
    }

    /**
     * 用户信息验证后置执行
     *
     * @param userDetailX    用户信息
     * @param authentication 登录凭证
     */
    @Override
    protected void afterCheckUser(UserDetailX userDetailX, Authentication authentication) {
    }

    /**
     * 判断是上面 authenticate 方法的 authentication 参数，是哪种类型
     *
     * @param authentication 验证方式
     * @return 是否支持
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return (LoginToken.class.isAssignableFrom(authentication));
    }

    /**
     * Determine the types of data sources supported by this class
     *
     * @return Supported types
     */
    @Override
    public String supports() {
        return LoginTypeEnum.WEB.getSlogan();
    }

}

